package com.kefu.service.impl;

import com.kefu.dto.MessageDTO;
import com.kefu.dto.SessionDTO;
import com.kefu.dto.UserDTO;
import com.kefu.entity.Message;
import com.kefu.entity.Session;
import com.kefu.entity.User;
import com.kefu.repository.MessageRepository;
import com.kefu.repository.SessionRepository;
import com.kefu.repository.UserRepository;
import com.kefu.service.SessionService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.stream.Collectors;

@Service
public class SessionServiceImpl implements SessionService {

    @Autowired
    private SessionRepository sessionRepository;

    @Autowired
    private MessageRepository messageRepository;

    @Autowired
    private UserRepository userRepository;

    @Override
    public List<SessionDTO> getSessionsByAdminId(String adminId) {
        // 1. 查询所有未分配（adminId为null）且有未读消息的会话（供客服抢单）
        List<Session> unassignedSessions = sessionRepository.findByAdminIdIsNullAndUnreadCountGreaterThan(0);
        // 2. 查询已分配给当前客服的会话
        List<Session> assignedSessions = sessionRepository.findByAdminIdOrderByLastMessageTimeDesc(adminId);

        // 合并列表：未分配未读会话优先展示
        List<Session> allSessions = new ArrayList<>();
        allSessions.addAll(unassignedSessions);
        allSessions.addAll(assignedSessions);

        return allSessions.stream().map(this::convertToDTO).collect(Collectors.toList());
    }

    // 标记消息为已读时，绑定会话到当前客服（如果未绑定）
    @Override
    public boolean markMessagesAsRead(String sessionId, String adminId) {
        Session session = sessionRepository.findById(sessionId)
                .orElseThrow(() -> new RuntimeException("会话不存在"));

        // 如果会话未绑定客服，绑定到当前读取的客服
        if (session.getAdminId() == null) {
            session.setAdminId(adminId);
        }

        // 验证权限（仅绑定的客服可标记已读）
        if (!adminId.equals(session.getAdminId())) {
            throw new RuntimeException("无权操作此会话");
        }

        // 标记消息为已读
        int updated = messageRepository.markAsReadBySessionId(sessionId);
        session.setUnreadCount(0);
        sessionRepository.save(session);

        return updated > 0;
    }


    @Override
    public SessionDTO createSession(String userId) {
        // 创建会话
        Session session = new Session();
        session.setId(UUID.randomUUID().toString().replace("-", ""));
        session.setUserId(userId);
        session.setAdminId("admin_001");
        session.setStatus(0); // 等待中
        session.setCreateTime(new Date());
        session.setUnreadCount(0);
        sessionRepository.save(session);

        return convertToDTO(session);
    }

    @Override
    public List<SessionDTO> getUserSessions(String userId) {
        List<Session> sessions = sessionRepository.findByUserIdOrderByLastMessageTimeDesc(userId);
        return sessions.stream()
                .map(this::convertToDTO)
                .collect(Collectors.toList());
    }

    @Override
    public MessageDTO sendMessage(String sessionId, String senderId, int senderType, String content, int messageType) {
        // 验证会话
        Session session = sessionRepository.findById(sessionId)
                .orElseThrow(() -> new RuntimeException("会话不存在"));

        // 创建消息
        Message message = new Message();
        message.setId(UUID.randomUUID().toString().replace("-", ""));
        message.setSessionId(sessionId);
        message.setSenderId(senderId);
        message.setSenderType(senderType);
        message.setContent(content);
        message.setMessageType(messageType);
        message.setReadStatus(0); // 未读
        message.setSendTime(new Date());
        messageRepository.save(message);

        // 更新会话信息
        session.setLastMessage(messageType == 2 ? "[图片]" : content);
        session.setLastMessageTime(new Date());
        session.setStatus(1); // 进行中

        // 如果是用户发送的消息，增加未读计数
        if (senderType == 1) {
            session.setUnreadCount(session.getUnreadCount() + 1);
        }

        sessionRepository.save(session);

        return convertToDTO(message);
    }

    @Override
    public Map<String, Object> getSessionMessages(String sessionId, String userId) {
        // 验证会话
        Session session = sessionRepository.findById(sessionId)
                .orElseThrow(() -> new RuntimeException("会话不存在"));

        // 查询消息
        List<Message> messages = messageRepository.findBySessionIdOrderBySendTimeAsc(sessionId);

        // 转换为DTO
        List<MessageDTO> messageDTOs = messages.stream()
                .map(this::convertToDTO)
                .collect(Collectors.toList());

        // 构建结果
        Map<String, Object> result = new HashMap<>();
        result.put("messages", messageDTOs);
        result.put("sessionId", sessionId);
        result.put("unreadCount", session.getUnreadCount());

        return result;
    }

    @Override
    public boolean endSession(String sessionId, String operatorId, int operatorType) {
        // 验证会话
        Session session = sessionRepository.findById(sessionId)
                .orElseThrow(() -> new RuntimeException("会话不存在"));

        // 检查权限
        if (operatorType == 1 && !operatorId.equals(session.getUserId())) {
            throw new RuntimeException("无权结束此会话");
        }
        if (operatorType == 2 && !operatorId.equals(session.getAdminId())) {
            throw new RuntimeException("无权结束此会话");
        }

        // 更新会话状态
        session.setStatus(2); // 已结束
        session.setEndTime(new Date());
        sessionRepository.save(session);
        return true;
    }

    // 转换工具：Session -> SessionDTO
    private SessionDTO convertToDTO(Session session) {
        SessionDTO dto = new SessionDTO();
        dto.setId(session.getId());
        dto.setUserId(session.getUserId());
        dto.setAdminId(session.getAdminId());
        dto.setStatus(session.getStatus());
        dto.setLastMessage(session.getLastMessage());
        dto.setLastMessageTime(session.getLastMessageTime());
        dto.setUnreadCount(session.getUnreadCount());
        dto.setCreateTime(session.getCreateTime());

        // 关联用户信息
        if (session.getUserId() != null) {
            User user = userRepository.findById(session.getUserId()).orElse(null);
            if (user != null) {
                UserDTO userDTO = new UserDTO();
                userDTO.setId(user.getId());
                userDTO.setPhone(user.getPhone());
                userDTO.setNickname(user.getNickname());
                userDTO.setAvatar(user.getAvatar());
                dto.setUser(userDTO);
            }
        }

        return dto;
    }

    // 转换工具：Message -> MessageDTO
    private MessageDTO convertToDTO(Message message) {
        MessageDTO dto = new MessageDTO();
        dto.setId(message.getId());
        dto.setSessionId(message.getSessionId());
        dto.setSenderId(message.getSenderId());
        dto.setSenderType(message.getSenderType());
        dto.setContent(message.getContent());
        dto.setMessageType(message.getMessageType());
        dto.setReadStatus(message.getReadStatus());
        dto.setSendTime(message.getSendTime());
        return dto;
    }

    @Override
    public List<SessionDTO> getAllUnreadSessions() {
        // 查询所有有未读消息的会话（无论是否分配客服）
        List<Session> unreadSessions = sessionRepository.findAllWithUnreadMessages();
        return unreadSessions.stream()
                .map(this::convertToDTO)
                .collect(Collectors.toList());
    }

    @Override
    public SessionDTO bindSessionToAdmin(String sessionId, String adminId) {
        // 1. 验证会话是否存在
        Session session = sessionRepository.findById(sessionId)
                .orElseThrow(() -> new RuntimeException("会话不存在"));

        // 2. 检查会话是否已被绑定
        if (session.getAdminId() != null && !session.getAdminId().isEmpty()) {
            throw new RuntimeException("该会话已被其他客服绑定");
        }

        // 3. 执行绑定操作（更新数据库）
        int affected = sessionRepository.bindSessionToAdmin(sessionId, adminId);
        if (affected <= 0) {
            throw new RuntimeException("绑定会话失败");
        }

        // 4. 返回更新后的会话信息
        Session updatedSession = sessionRepository.findById(sessionId).orElseThrow(() -> new RuntimeException("会话不存在"));
        return convertToDTO(updatedSession);
    }
}
